/*-------------------------------------------------------------------------
 *
 * 文件和目录权限例程
 *
 *
 * Portions Copyright (c) 1996-2022, PostgreSQL Global Development Group
 * Portions Copyright (c) 1994, Regents of the University of California
 *
 * src/common/file_perm.c
 *
 *-------------------------------------------------------------------------
 */
#include "c.h"

#include "common/file_perm.h"

/* 创建数据目录中的目录和文件的模式 */
int			pg_dir_create_mode = PG_DIR_MODE_OWNER;
int			pg_file_create_mode = PG_FILE_MODE_OWNER;

/*
 * 传递给 umask() 的模式掩码。这更多的是一种预防措施，
 * 因为所有文件/目录创建都应该使用上述创建模式进行。
 */
int			pg_mode_mask = PG_MODE_MASK_OWNER;

/*
 * 根据传递的数据目录模式设置在写入 PGDATA 时使用的创建模式和掩码。
 * 如果模式中存在组读取/执行权限，则创建模式和掩码将放宽，以允许
 * 对所有新创建的文件和目录进行组读取/执行。
 */
void SetDataDirectoryCreatePerm(int fc_dataDirMode)
{
	/* 如果数据目录模式具有组访问权限 */
	if ((PG_DIR_MODE_GROUP & fc_dataDirMode) == PG_DIR_MODE_GROUP)
	{
		pg_dir_create_mode = PG_DIR_MODE_GROUP;
		pg_file_create_mode = PG_FILE_MODE_GROUP;
		pg_mode_mask = PG_MODE_MASK_GROUP;
	}
	/* 否则使用默认权限 */
	else
	{
		pg_dir_create_mode = PG_DIR_MODE_OWNER;
		pg_file_create_mode = PG_FILE_MODE_OWNER;
		pg_mode_mask = PG_MODE_MASK_OWNER;
	}
}

#ifdef FRONTEND

/*
 * 通过检查 PGDATA 目录的模式并调用 SetDataDirectoryCreatePerm()
 * 来获取在写入 PGDATA 时使用的创建模式和掩码。
 *
 * 此处不处理错误，应由应用程序在返回 false 时报告。
 *
 * 在 Windows 上抑制，因为可能没有对 Unix 风格
 * 文件权限的适当支持。
 */
bool GetDataDirectoryCreatePerm(const char *fc_dataDir)
{
#if !defined(WIN32) && !defined(__CYGWIN__)
	struct stat fc_statBuf;

	/*
	 * 如果获取模式时发生错误，则返回 false。调用者有
	 * 责任生成错误（如果适当），指示我们无法访问数据目录。
	 */
	if (stat(fc_dataDir, &fc_statBuf) == -1)
		return false;

	/* 设置权限 */
	SetDataDirectoryCreatePerm(fc_statBuf.st_mode);
	return true;
#else							/* !defined(WIN32) && !defined(__CYGWIN__) */
	/*
	 * 在 Windows 上，我们这里没有任何事情要做，因为它们没有
	 * Unix 风格的权限。
	 */
	return true;
#endif
}


#endif							/* FRONTEND */
